#include "stdafx.h"
#include "ESWin32View.h"

#if (CURRENT_PLATFORM == PLATFORM_WIN32_VS)

ESWin32View::ESWin32View()
:m_wcsTitle(0), m_iFlags(0),
m_hWnd(0), m_eglDisplay(0), m_eglContext(0), m_eglSurface(0)
{}

ESWin32View::ESWin32View(__UINT32 iWidth, __UINT32 iHeight, TCHAR* wcsTitle, __UINT32 iFlags)
: m_wcsTitle(wcsTitle), m_iFlags(iFlags),
m_hWnd(0), m_eglDisplay(0), m_eglContext(0), m_eglSurface(0)
{
	m_iWidth = iWidth;
	m_iHeight = iHeight;
}

ESWin32View::~ESWin32View()
{

}

__VOID ESUTIL_API ESWin32View::esInitWinView(ESWin32View* esWin32View)
{
	if (!esWin32View)
	{
		memset(esWin32View, 0, sizeof(ESWin32View));
	}
}

EGLBoolean ESUTIL_API ESWin32View::esCreateWindows()
{
	EGLint attribList[] =
	{
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, (m_iFlags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,
		EGL_DEPTH_SIZE, (m_iFlags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE,
		EGL_STENCIL_SIZE, (m_iFlags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,
		EGL_SAMPLE_BUFFERS, (m_iFlags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
		EGL_NONE
	};

	if (!esCreateClientWindows())
	{
		return GL_FALSE;
	}

	if (!esCreateESContext(attribList))
	{
		return GL_FALSE;
	}

	return GL_TRUE;
}

EGLBoolean ESWin32View::esCreateClientWindows()
{
	WNDCLASS wndclass = { 0 };
	DWORD    wStyle = 0;
	RECT     windowRect;
	HINSTANCE hInstance = GetModuleHandle(NULL);


	wndclass.style = CS_OWNDC;
	wndclass.lpfnWndProc = (WNDPROC)esWindowProc;
	wndclass.hInstance = hInstance;
	wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndclass.lpszClassName = TEXT("opengles2.0");

	if (!RegisterClass(&wndclass))
		return FALSE;

	wStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;

	// Adjust the window rectangle so that the client area has
	// the correct number of pixels
	windowRect.left = 0;
	windowRect.top = 0;
	windowRect.right = m_iWidth;
	windowRect.bottom = m_iHeight;

	AdjustWindowRect(&windowRect, wStyle, FALSE);

	m_hWnd = CreateWindow(
		TEXT("opengles2.0"),
		m_wcsTitle,
		wStyle,
		0,
		0,
		windowRect.right - windowRect.left,
		windowRect.bottom - windowRect.top,
		NULL,
		NULL,
		hInstance,
		NULL);

	if (m_hWnd == NULL)
		return GL_FALSE;

	ShowWindow(m_hWnd, TRUE);

	return GL_TRUE;
}

EGLBoolean ESWin32View::esCreateESContext(EGLint attribList[])
{
	EGLint numConfigs;
	EGLint majorVersion;
	EGLint minorVersion;
	EGLDisplay display;
	EGLContext context;
	EGLSurface surface;
	EGLConfig config;
	EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };

	// Get Display
	display = eglGetDisplay(GetDC(m_hWnd));
	if (display == EGL_NO_DISPLAY)
	{
		return EGL_FALSE;
	}

	// Initialize EGL
	if (!eglInitialize(display, &majorVersion, &minorVersion))
	{
		return EGL_FALSE;
	}

	// Get configs
	if (!eglGetConfigs(display, NULL, 0, &numConfigs))
	{
		return EGL_FALSE;
	}

	// Choose config
	if (!eglChooseConfig(display, attribList, &config, 1, &numConfigs))
	{
		return EGL_FALSE;
	}

	// Create a surface
	surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_hWnd, NULL);
	if (surface == EGL_NO_SURFACE)
	{
		return EGL_FALSE;
	}

	// Create a GL context
	context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
	if (context == EGL_NO_CONTEXT)
	{
		return EGL_FALSE;
	}

	// Make the context current
	if (!eglMakeCurrent(display, surface, surface, context))
	{
		return EGL_FALSE;
	}

	m_eglDisplay = display;
	m_eglSurface = surface;
	m_eglContext = context;
	return EGL_TRUE;
}

LRESULT ESWin32View::esWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT  lRet = 1;

	switch (uMsg)
	{
	case WM_CREATE:
		break;

	case WM_PAINT:
	{
					 ValidateRect(hWnd, NULL);
	}
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		
		break;

	case WM_KEYDOWN:
	{
	}
		break;

	case WM_KEYUP:
	{
	}
		break;

	default:
		lRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
		break;
	}

	return lRet;
}

__VOID ESWin32View::Update()
{
	//Handle win32 message
	MSG msg = { 0 };

	int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0);
	if (gotMsg)
	{
		if (msg.message == WM_QUIT)
		{
			m_bIsQuit = true;
		}
		else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	else
	{
		SendMessage(m_hWnd, WM_PAINT, 0, 0);
	}

	eglSwapBuffers(m_eglDisplay, m_eglSurface);
}

__VOID ESWin32View::Destroy()
{
	SAFE_DEL(m_wcsTitle);
}

#endif